package com.jichangxiu.framework.aspect;

import com.jichangxiu.common.annotation.Tenant;
import com.jichangxiu.common.context.JcxContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;

@Aspect
@Slf4j
@Component
public class TenantAspect {

    @Pointcut("@within(com.jichangxiu.common.annotation.Tenant) " +
            "|| @annotation(com.jichangxiu.common.annotation.Tenant)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object object;
        try {
            Class<?> targetClass = proceedingJoinPoint.getTarget().getClass();
            Tenant classTenant = targetClass.getAnnotation(Tenant.class);
            MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
            Method method = signature.getMethod();
            Tenant methodTenant = method.getAnnotation(Tenant.class);
            // 判断类上是否有注解
            boolean isClassAnnotated = AnnotationUtils.isAnnotationDeclaredLocally(Tenant.class, targetClass);
            // 判断方法上是否有注解
            boolean isMethodAnnotated = Objects.nonNull(methodTenant);
            // 如果类上有
            if (isClassAnnotated)
                JcxContext.setEnabledTenant(classTenant.noTenant());
            // 如果方法上有 以方法上的为主
            if (isMethodAnnotated)
                JcxContext.setEnabledTenant(methodTenant.noTenant());
            object = proceedingJoinPoint.proceed();
        } finally {
            JcxContext.clearEnabledTenant();
        }
        return object;
    }

}
